import 'dart:ui';

import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'package:flutter_massage/common_lib/index.dart';
import 'package:flutter_massage/generated/assets.dart';
import 'package:flutter_massage/values/index.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:flutter_svg/flutter_svg.dart';

///@describe 通用的list的item的结构
///------------------------------
///----- left | center | right --
///----- bottom -----------------
class CommonListItemScaffold extends StatelessWidget {
  const CommonListItemScaffold({
    this.left,
    this.center,
    this.right,
    this.bottom,
    this.onTap,
    this.crossAxisAlignment = CrossAxisAlignment.center,
    this.mainAxisAlignment = MainAxisAlignment.start,
    this.onLongPress,
    this.mainAxisSize = MainAxisSize.max,
    this.contentPadding,
    this.hasInkWell = false,
    Key? key,
  }) : super(key: key);

  final Widget? left;
  final Widget? center;
  final Widget? right;
  final Widget? bottom;
  final Function()? onTap;
  final CrossAxisAlignment crossAxisAlignment;
  final MainAxisAlignment mainAxisAlignment;
  final Function()? onLongPress;
  final MainAxisSize mainAxisSize;
  final EdgeInsets? contentPadding;
  final bool hasInkWell;

  @override
  Widget build(BuildContext context) {
    var topChildren = <Widget>[];
    if (left != null) topChildren.add(left!);
    if (center != null) topChildren.add(center!);
    if (right != null) topChildren.add(right!);
    var top = Row(
      mainAxisSize: mainAxisSize,
      crossAxisAlignment: crossAxisAlignment,
      mainAxisAlignment: MainAxisAlignment.start,
      children: topChildren,
    );

    Widget content = top;
    if (bottom != null) {
      content = Column(
        mainAxisSize: MainAxisSize.min,
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [top, bottom!],
      );
    }

    return onTap == null && onLongPress == null
        ? Container(
            padding: contentPadding,
            child: content,
          )
        : ButtonWidget(
            onTap: onTap,
            padding: contentPadding,
            onLongPress: onLongPress,
            hasInkWell: hasInkWell,
            child: content,
          );
  }
}

///虚线描边控件
class DashBorder extends StatelessWidget {
  DashBorder(
    this.child, {
    Key? key,
    CustomPainter? paint,
    double? defaultWidth,
    Color? defaultColor,
    double? defaultDashWidth,
    double? defaultDashGap,
  })  : paint = paint ??
            _DashBorderPaint(
              defaultWidth ?? 1.w,
              defaultColor ?? Colors.black,
              defaultDashWidth ?? 3.w,
              defaultDashGap ?? 3.w,
            ),
        super(key: key);
  final Widget child;
  final CustomPainter? paint;

  @override
  Widget build(BuildContext context) {
    return CustomPaint(
      painter: paint,
      child: child,
    );
  }
}

class _DashBorderPaint extends CustomPainter {
  _DashBorderPaint(this.width, this.color, this.dashWidth, this.dashGap);

  final Color color;
  final double dashWidth;
  final double dashGap;
  final double width;

  @override
  void paint(Canvas canvas, Size size) {
    Paint paint = Paint()
      ..color = color
      ..strokeWidth = width
      ..strokeCap = StrokeCap.round
      ..isAntiAlias = true
      ..style = PaintingStyle.stroke;

    Path path = Path();
    Path paintPath = Path();
    path.addRect(Rect.fromLTWH(0, 0, size.width, size.height));
    double distance = 0;
    for (PathMetric pathMetric in path.computeMetrics()) {
      while (distance < pathMetric.length) {
        paintPath.addPath(pathMetric.extractPath(distance, distance + dashWidth), Offset.zero);
        distance += dashWidth + dashGap;
      }
    }
    canvas.drawPath(paintPath, paint);
  }

  @override
  bool shouldRepaint(_DashBorderPaint oldDelegate) {
    return color != oldDelegate.color ||
        dashWidth != oldDelegate.dashWidth ||
        dashGap != oldDelegate.dashGap ||
        width != oldDelegate.width;
  }
}

class CommonDropPointer extends StatelessWidget {
  CommonDropPointer(
    this.absorbing, {
    Key? key,
    this.child,
  }) : super(key: key);

  final bool Function() absorbing;
  final Widget? child;
  final drop = [false];

  @override
  Widget build(BuildContext context) {
    return Listener(
      onPointerCancel: (_) {
        drop[0] = false;
      },
      onPointerUp: (_) {
        drop[0] = false;
      },
      child: CommonAbsorbPointer(
        () {
          bool b = absorbing();
          if (b) {
            drop[0] = true;
          }
          return drop[0] || b;
        },
        child: child,
      ),
    );
  }
}

class CommonAbsorbPointer extends SingleChildRenderObjectWidget {
  const CommonAbsorbPointer(
    this.absorbing, {
    Key? key,
    Widget? child,
  }) : super(key: key, child: child);

  final bool Function() absorbing;

  @override
  RenderCommonAbsorbPointer createRenderObject(BuildContext context) {
    return RenderCommonAbsorbPointer(absorbing);
  }

  @override
  void updateRenderObject(BuildContext context, RenderCommonAbsorbPointer renderObject) {
    renderObject.absorbing = absorbing;
  }
}

class RenderCommonAbsorbPointer extends RenderProxyBox {
  RenderCommonAbsorbPointer(
    bool Function() absorbing, {
    RenderBox? child,
  })  : _absorbing = absorbing,
        super(child);

  bool Function() get absorbing => _absorbing;

  bool Function() _absorbing;

  set absorbing(bool Function() value) {
    if (_absorbing == value) return;
    _absorbing = value;
  }

  @override
  bool hitTest(BoxHitTestResult result, {required Offset position}) {
    return absorbing() ? size.contains(position) : super.hitTest(result, position: position);
  }
}

///间距组件
class CommonMargin extends StatelessWidget {
  const CommonMargin({Key? key, this.width, this.height}) : super(key: key);

  const CommonMargin.width(this.width, {Key? key})
      : height = null,
        super(key: key);

  const CommonMargin.height(this.height, {Key? key})
      : width = null,
        super(key: key);

  final double? width;
  final double? height;

  @override
  Widget build(BuildContext context) {
    return SizedBox(width: width, height: height);
  }
}

class CommonItemComponent extends StatelessWidget {
  const CommonItemComponent(
    this.data, {
    Key? key,
    this.padding,
    this.itemHeight,
    this.iconSize,
    this.iconTitleMargin,
    this.titleFontSize = 16,
    this.titleColor = AppColors.textLevelOne,
    this.titleFontWeight,
    this.contentFontSize = 14,
    this.contentColor = AppColors.textLevelTwo,
    this.contentFontWeight,
    this.lineHeight = 0.5,
    this.lineColor = AppColors.line,
    this.lineMargin = 0,
    this.showArrow = true,
    this.arrowWidth,
    this.hasLine = true,
  }) : super(key: key);

  final CommonItemBean data;

  final EdgeInsets? padding;
  final double? itemHeight;

  ///图标样式
  final double? iconSize;

  ///图标和icon的距离
  final double? iconTitleMargin;

  ///标题样式
  final double titleFontSize;
  final Color titleColor;
  final FontWeight? titleFontWeight;

  ///内容样式
  final double contentFontSize;
  final Color contentColor;
  final FontWeight? contentFontWeight;

  ///分割线样式
  final double lineHeight;
  final Color lineColor;
  final double lineMargin;

  ///箭头
  final bool showArrow;
  final double? arrowWidth;

  ///分割线
  final bool hasLine;

  @override
  Widget build(BuildContext context) {
    List<Widget> children = [];

    ///图标
    if (data.icon.notEmpty) {
      children.add(_buildIcon());
      children.add(CommonMargin.width(iconTitleMargin ?? 12.w));
    }

    ///标题
    children.add(_buildTitle());
    children.add(CommonMargin.width(5.w));

    ///内容
    children.add(const Spacer());
    children.add(_buildContent());

    ///箭头
    if (showArrow) {
      children.add(CommonMargin.width(12.w));
      children.add(_buildArrow());
    }

    return ColoredBox(
      color: AppColors.white,
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          ButtonWidget(
            padding: padding ?? EdgeInsets.all(16.w),
            hasInkWell: false,
            onTap: data.onTap,
            height: itemHeight,
            child: Row(children: children),
          ),
          if (hasLine)
            CommonDivider(marginLeft: lineMargin, marginRight: lineMargin, color: lineColor, height: lineHeight.w),
        ],
      ),
    );
  }

  ///图标
  Widget _buildIcon() => SvgPicture.asset(data.icon ?? '', width: iconSize ?? 22.w, height: iconSize ?? 22.w);

  ///标题
  Widget _buildTitle() => TextWidget.oneLine(
        text: data.title,
        fontSize: titleFontSize,
        color: titleColor,
        fontWeight: titleFontWeight,
      );

  ///内容
  Widget _buildContent() {
    return data.contentWidget != null
        ? data.contentWidget!
        : TextWidget.oneLine(
            text: data.content ?? '',
            fontSize: contentFontSize,
            color: contentColor,
            fontWeight: contentFontWeight,
          );
  }

  ///箭头
  Widget _buildArrow() => Padding(
        padding: EdgeInsets.only(bottom: 1.w),
        child: SvgPicture.asset(Assets.svgArrowRightGray, width: arrowWidth ?? 5.w),
      );
}

class CommonItemBean {
  CommonItemBean({
    required this.title,
    this.content,
    this.icon,
    this.contentWidget,
    this.onTap,
  });

  final String title;
  final String? icon;
  final String? content;
  final Widget? contentWidget;
  final VoidCallback? onTap;
}

class OneModuleComponent extends StatelessWidget {
  const OneModuleComponent(
    this.title,
    this.child, {
    Key? key,
    this.titleFontSize = 16,
    this.titleColor = AppColors.textLevelOne,
    this.titleFontWeight = FontWeight.normal,
    this.paddingTop = 0,
    this.paddingBottom = 0,
    this.paddingLeft = 0,
    this.paddingRight = 0,
    this.show = true,
    this.all = "",
    this.onTap,
    this.icon,
    this.subTitle,
    this.divider,
    this.titleWidget,
    this.actionGroup,
    this.arrowWidth,
    this.allFontWeight,
  }) : super(key: key);

  final bool show;
  final String title;
  final double titleFontSize;
  final Color titleColor;
  final FontWeight titleFontWeight;
  final String all;
  final Function() child;
  final VoidCallback? onTap;
  final double paddingTop;
  final double paddingBottom;
  final double paddingLeft;
  final double paddingRight;
  final String? icon;
  final String? subTitle;
  final Widget? divider;
  final Widget? titleWidget;
  final List<Widget>? actionGroup;
  final double? arrowWidth;
  final FontWeight? allFontWeight;

  @override
  Widget build(BuildContext context) {
    if (!show) return Container();

    var children = <Widget>[];

    ///添加icon
    if (icon.notEmpty) {
      children.add(
        Padding(
          padding: EdgeInsets.only(right: 10.w),
          child: SvgPicture.asset(
            icon!,
            width: 16.w,
            height: 16.w,
          ),
        ),
      );
    }

    ///添加标题
    if (titleWidget != null) {
      children.add(titleWidget!);
    } else {
      if (title.notEmpty) {
        children.add(TextWidget.oneLine(
          text: title,
          fontSize: titleFontSize,
          color: titleColor,
          fontWeight: titleFontWeight,
        ));
      }
    }

    ///添加副标题
    if (subTitle.notEmpty) {
      children.add(
        Expanded(
          child: Padding(
            padding: EdgeInsets.only(left: 15.w),
            child: TextWidget.oneLine(text: subTitle!, fontSize: 13, color: AppColors.textLevelTwo),
          ),
        ),
      );
    }

    ///右侧按钮
    List<Widget> actionList = [
      Padding(
        padding: EdgeInsets.only(bottom: 1.w),
        child: TextWidget.oneLine(
          text: all,
          fontSize: 13,
          color: AppColors.textLevelOne,
          fontWeight: allFontWeight ?? FontWeight.bold,
        ),
      ),
      Padding(
        padding: EdgeInsets.only(left: 3.w, bottom: 1.w),
        child: Assets.svgArrowRightGray.toSvg(width: arrowWidth ?? 9.w, color: AppColors.textLevelOne),
      ),
    ];

    if (actionGroup != null && actionGroup!.isNotEmpty) actionList = actionGroup!;

    return Column(
      mainAxisSize: MainAxisSize.min,
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [
        CommonTitleScaffold(
          Row(children: children),
          paddingTop: paddingTop,
          paddingBottom: paddingBottom,
          paddingLeft: paddingLeft,
          paddingRight: paddingRight,
          actionGroup: actionList,
          divider: divider,
          onTap: onTap,
        ),
        child(),
      ],
    );
  }
}

///@describe 通用的标题架构
///[actionGroup] 多个控件组成的点击区域[onTap]为回调，同时设置生效
///[actions]多个操作按钮，自行添加点击。
class CommonTitleScaffold extends StatelessWidget {
  const CommonTitleScaffold(
    this.title, {
    Key? key,
    this.paddingLeft = 16,
    this.paddingTop = 20,
    this.paddingRight = 11,
    this.paddingBottom = 5,
    this.actionGroup,
    this.onTap,
    this.actions,
    this.divider,
  }) : super(key: key);

  final Widget title;
  final double paddingLeft;
  final double paddingTop;
  final double paddingRight;
  final double paddingBottom;
  final List<Widget>? actionGroup;
  final VoidCallback? onTap;
  final List<Widget>? actions;
  final Widget? divider;

  Widget getContent() {
    var child = Row(
      mainAxisAlignment: MainAxisAlignment.spaceBetween,
      crossAxisAlignment: CrossAxisAlignment.center,
      children: [
        Expanded(child: title),
        if (actionGroup != null && onTap != null)
          ButtonWidget(
            onTap: onTap,
            padding: EdgeInsets.all(5.w),
            hasInkWell: false,
            child: Row(mainAxisSize: MainAxisSize.min, children: actionGroup!),
          ),
        if (actions != null && actions!.isNotEmpty) Row(mainAxisSize: MainAxisSize.min, children: actions!),
      ],
    );
    if (divider != null) {
      return Column(children: [child, divider!]);
    }
    return child;
  }

  @override
  Widget build(BuildContext context) {
    return Container(
      padding: EdgeInsets.fromLTRB(
        paddingLeft.w,
        paddingTop.w,
        paddingRight.w,
        paddingBottom.w,
      ),
      child: getContent(),
    );
  }
}

///@describe 带描边的tag样式
class CommonTagText extends StatelessWidget {
  const CommonTagText(
    this.text, {
    Key? key,
    this.fontColor = AppColors.textLevelOne,
    this.fontSize = 12,
    this.fontWeight,
    this.bgColor = AppColors.grayEd,
    this.padding,
    this.radius = 4,
    this.borderWidth = 0.5,
    this.borderColor,
    this.onTap,
  }) : super(key: key);

  final String text;
  final Color fontColor;
  final Color bgColor;
  final EdgeInsetsGeometry? padding;
  final double radius;
  final double fontSize;
  final Color? borderColor;
  final double borderWidth;
  final VoidCallback? onTap;
  final FontWeight? fontWeight;

  @override
  Widget build(BuildContext context) {
    var tag = Container(
      padding: padding ?? EdgeInsets.fromLTRB(7.w, 6.w, 7.w, 6.w),
      decoration: CommonDecoration.getShapeDecoration(
        radius: radius,
        bg: bgColor,
        borderColor: borderColor,
        borderWidth: borderWidth,
      ),
      child: TextWidget.oneLine(
        text: text,
        fontSize: fontSize,
        color: fontColor,
        fontWeight: fontWeight ?? FontWeight.normal,
      ),
    );
    return onTap != null
        ? GestureDetector(
            onTap: onTap,
            child: tag,
          )
        : tag;
  }
}

///通用的点点
class CommonPoint extends StatelessWidget {
  const CommonPoint({
    Key? key,
    this.width = 0,
    this.height = 0,
    this.bg = Colors.red,
  }) : super(key: key);

  final double width;
  final double height;
  final Color bg;

  @override
  Widget build(BuildContext context) {
    return Container(
        width: width == 0 ? 9.w : width,
        height: height == 0 ? 9.w : height,
        decoration: CommonDecoration.getShapeDecoration(bg: bg));
  }
}

class CommonSafeBottomComponent extends StatelessWidget {
  const CommonSafeBottomComponent({
    Key? key,
    required this.child,
    this.color,
    this.ratio = 0.5,
  }) : super(key: key);

  final Widget child;
  final Color? color;
  final double ratio;

  @override
  Widget build(BuildContext context) {
    return Container(
      padding: EdgeInsets.only(bottom: ScreenUtil().bottomBarHeight * ratio),
      color: color,
      child: child,
    );
  }
}
